package com.wande.dataplatform.filecollection.validation.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.wande.dataplatform.filecollection.domain.dto.ValidationError;
import com.wande.dataplatform.filecollection.validation.IValidationRule;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Date;

/**
 * 范围校验规则
 * 校验数值或日期是否在指定范围内
 * 配置格式: {"type": "NUMBER|DATE", "min": "最小值", "max": "最大值", "minInclusive": true, "maxInclusive": true}
 *
 * @author wande
 */
@Slf4j
@Component
public class RangeValidationRule implements IValidationRule {

    @Override
    public String getRuleType() {
        return "RANGE";
    }

    @Override
    public ValidationError validate(String fieldName, Object value, String ruleConfig) {
        // 如果值为空，跳过校验
        if (value == null) {
            return null;
        }

        try {
            JSONObject config = JSONUtil.parseObj(ruleConfig);
            String type = config.getStr("type", "NUMBER");

            if ("NUMBER".equals(type)) {
                return validateNumber(fieldName, value, config);
            } else if ("DATE".equals(type)) {
                return validateDate(fieldName, value, config);
            } else {
                log.warn("不支持的范围校验类型: {}", type);
                return null;
            }
        } catch (Exception e) {
            log.error("范围校验规则执行失败: {}", e.getMessage());
            return new ValidationError(
                fieldName,
                getRuleType(),
                String.format("字段 [%s] 范围校验失败: %s", fieldName, e.getMessage()),
                value,
                null
            );
        }
    }

    /**
     * 校验数值范围
     */
    private ValidationError validateNumber(String fieldName, Object value, JSONObject config) {
        try {
            BigDecimal numValue = new BigDecimal(value.toString());
            String minStr = config.getStr("min");
            String maxStr = config.getStr("max");
            boolean minInclusive = config.getBool("minInclusive", true);
            boolean maxInclusive = config.getBool("maxInclusive", true);

            // 检查最小值
            if (StrUtil.isNotBlank(minStr)) {
                BigDecimal min = new BigDecimal(minStr);
                int compareMin = numValue.compareTo(min);
                
                if (minInclusive && compareMin < 0) {
                    return new ValidationError(
                        fieldName,
                        getRuleType(),
                        String.format("字段 [%s] 的值 %s 小于最小值 %s", fieldName, value, minStr),
                        value,
                        null
                    );
                } else if (!minInclusive && compareMin <= 0) {
                    return new ValidationError(
                        fieldName,
                        getRuleType(),
                        String.format("字段 [%s] 的值 %s 必须大于 %s", fieldName, value, minStr),
                        value,
                        null
                    );
                }
            }

            // 检查最大值
            if (StrUtil.isNotBlank(maxStr)) {
                BigDecimal max = new BigDecimal(maxStr);
                int compareMax = numValue.compareTo(max);
                
                if (maxInclusive && compareMax > 0) {
                    return new ValidationError(
                        fieldName,
                        getRuleType(),
                        String.format("字段 [%s] 的值 %s 大于最大值 %s", fieldName, value, maxStr),
                        value,
                        null
                    );
                } else if (!maxInclusive && compareMax >= 0) {
                    return new ValidationError(
                        fieldName,
                        getRuleType(),
                        String.format("字段 [%s] 的值 %s 必须小于 %s", fieldName, value, maxStr),
                        value,
                        null
                    );
                }
            }

            return null;
        } catch (NumberFormatException e) {
            return new ValidationError(
                fieldName,
                getRuleType(),
                String.format("字段 [%s] 的值 %s 不是有效的数值", fieldName, value),
                value,
                null
            );
        }
    }

    /**
     * 校验日期范围
     */
    private ValidationError validateDate(String fieldName, Object value, JSONObject config) {
        try {
            Date dateValue = DateUtil.parse(value.toString());
            String minStr = config.getStr("min");
            String maxStr = config.getStr("max");
            boolean minInclusive = config.getBool("minInclusive", true);
            boolean maxInclusive = config.getBool("maxInclusive", true);

            // 检查最小日期
            if (StrUtil.isNotBlank(minStr)) {
                Date min = DateUtil.parse(minStr);
                int compareMin = dateValue.compareTo(min);
                
                if (minInclusive && compareMin < 0) {
                    return new ValidationError(
                        fieldName,
                        getRuleType(),
                        String.format("字段 [%s] 的日期 %s 早于最小日期 %s", fieldName, value, minStr),
                        value,
                        null
                    );
                } else if (!minInclusive && compareMin <= 0) {
                    return new ValidationError(
                        fieldName,
                        getRuleType(),
                        String.format("字段 [%s] 的日期 %s 必须晚于 %s", fieldName, value, minStr),
                        value,
                        null
                    );
                }
            }

            // 检查最大日期
            if (StrUtil.isNotBlank(maxStr)) {
                Date max = DateUtil.parse(maxStr);
                int compareMax = dateValue.compareTo(max);
                
                if (maxInclusive && compareMax > 0) {
                    return new ValidationError(
                        fieldName,
                        getRuleType(),
                        String.format("字段 [%s] 的日期 %s 晚于最大日期 %s", fieldName, value, maxStr),
                        value,
                        null
                    );
                } else if (!maxInclusive && compareMax >= 0) {
                    return new ValidationError(
                        fieldName,
                        getRuleType(),
                        String.format("字段 [%s] 的日期 %s 必须早于 %s", fieldName, value, maxStr),
                        value,
                        null
                    );
                }
            }

            return null;
        } catch (Exception e) {
            return new ValidationError(
                fieldName,
                getRuleType(),
                String.format("字段 [%s] 的值 %s 不是有效的日期格式", fieldName, value),
                value,
                null
            );
        }
    }

    @Override
    public boolean isValidConfig(String ruleConfig) {
        try {
            JSONObject config = JSONUtil.parseObj(ruleConfig);
            String type = config.getStr("type", "NUMBER");
            
            if (!"NUMBER".equals(type) && !"DATE".equals(type)) {
                return false;
            }

            String min = config.getStr("min");
            String max = config.getStr("max");

            // 至少需要配置最小值或最大值之一
            if (StrUtil.isBlank(min) && StrUtil.isBlank(max)) {
                return false;
            }

            // 验证数值格式
            if ("NUMBER".equals(type)) {
                if (StrUtil.isNotBlank(min) && !NumberUtil.isNumber(min)) {
                    return false;
                }
                if (StrUtil.isNotBlank(max) && !NumberUtil.isNumber(max)) {
                    return false;
                }
            }

            return true;
        } catch (Exception e) {
            log.error("范围校验规则配置无效: {}", e.getMessage());
            return false;
        }
    }
}
